package com.webflux.webflux02.handler;

import com.webflux.webflux02.entity.Product;
import com.webflux.webflux02.entity.ProductCriteria;
import com.webflux.webflux02.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.reactive.TransactionalOperator;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.Map;

@Component
public class ProductHandler {

    @Autowired
    private ProductService service;

    @Autowired
    private TransactionalOperator transactionalOperator;

    public Mono<ServerResponse> hello(ServerRequest serverRequest){

       return ServerResponse.ok().bodyValue("helo spring webflux");

    }

    /**
     * 保存多个
     * @param serverRequest
     * @return
     */
    //@Transactional //自动事物
    public Mono<ServerResponse> saveMany(ServerRequest serverRequest){
        return serverRequest.bodyToFlux(Product.class)
            .flatMap(p->service.save(p))
            .then(ServerResponse.ok().bodyValue("save success!"))
            .as(transactionalOperator::transactional);//手动事物
}

    public Mono<ServerResponse> findByPage(ServerRequest serverRequest){
        return serverRequest.bodyToMono(ProductCriteria.class)
                .flatMap(p->ServerResponse.ok().body(service.findByPage(p),Product.class));
    }


    public Mono<ServerResponse> save(ServerRequest request){

        Map<String,String> m = new HashMap<>(5);


        System.out.println("保存产品");

        return request.bodyToMono(Product.class)
                .flatMap(item -> service.save(item))
                .flatMap(item -> ServerResponse.ok().bodyValue(item));
    }

    public Mono<ServerResponse> queryAll(ServerRequest request){
        return ServerResponse.ok().body(service.findAll(),Product.class);
    }

    public Mono<ServerResponse> findById(ServerRequest request){
       Integer id = Integer.valueOf(request.pathVariable("productId"));
        return service.findById(id)
                .flatMap(ServerResponse.ok()::bodyValue)
                .switchIfEmpty(ServerResponse.notFound().build());
    }

    public Mono<ServerResponse> update(ServerRequest request){
        Integer id = Integer.valueOf(request.pathVariable("productId"));

        return service.findById(id).flatMap(p -> request.bodyToMono(Product.class))
                .flatMap(p -> service.updateById(p))
                .flatMap(p -> ServerResponse.ok().bodyValue(p))
                .switchIfEmpty(ServerResponse.notFound().build());
    }

    public Mono<ServerResponse> delete(ServerRequest request){
        Integer id = Integer.valueOf(request.pathVariable("productId"));

        return service.delete(id).flatMap(p ->ServerResponse.ok().bodyValue(p))
                .switchIfEmpty(ServerResponse.notFound().build());
    }


    public Mono<ServerResponse> findAll(ServerRequest request){
        Flux<Product> flux = Flux.generate(()->3,(productId,slink)->{
            service.findById(productId).subscribe(slink::next);
            if(productId >=10){
              slink.complete();
            }
            return productId + 1;
        });
        flux.subscribe(System.out::println);
        return ServerResponse.ok().body(flux,Product.class);

    }





}
